///////////////////////////////
// Analizador sintáctico C
///////////////////////////////

parser grammar AnasintC;

options {
  language = Java;
  tokenVocab = AnalexC;
}

@header {
  package practpl.seis;
}

@members {
     private ArrayList<RecognitionException> errors = new ArrayList<RecognitionException>();
     public ArrayList<RecognitionException> getErrors() {
        return errors;
     }
     @Override
     public void reportError (RecognitionException e) {
        String msg = getErrorMessage(e, getTokenNames());
        System.err.println(msg);
        errors.add(e);
     }
}

entrada: main;

main: tipodedato IDENT argumentos LLAVEA (buclewhile | buclefor | sentenciaif | declaracionvar | asignacion SEPARADOR | llamada)* LLAVEC;
buclewhile: WHILE PARENTESISA comparacion ((OR | AND) comparacion)* PARENTESISC LLAVEA (sentenciaif | asignacion SEPARADOR |condic_aritmetico)+ LLAVEC;
sentenciaif: IF (NOT)? PARENTESISA (comparacion | sentenciabreak | llamada)+ PARENTESISC (asignacion SEPARADOR | LLAVEA (asignacion SEPARADOR |llamada|sentenciabreak)+ LLAVEC);
sentenciabreak: BREAK SEPARADOR;

buclefor: FOR PARENTESISA asignacion? SEPARADOR comparacion? SEPARADOR (inc|dec)? PARENTESISC sentenciasfor;
sentenciasfor: ((asignacion SEPARADOR | inc SEPARADOR | dec SEPARADOR) | (LLAVEA (asignacion SEPARADOR | inc SEPARADOR | dec SEPARADOR | buclefor | buclewhile | sentenciaif)* LLAVEC));

inc: IDENT MAS MAS;
dec: IDENT MENOS MENOS;

comparacion: (NOT)? (NUMERO)? (MULT)? IDENT comparadores (IDENT | NUMERO);
declaracionvar: tipodedato IDENT (COMA IDENT)* SEPARADOR;
asignacion: (tipodedato)? IDENT IGUAL (MENOS PARENTESISA)? (NUMERO | FLOAT | IDENT) (operadores NUMERO)? (PARENTESISC)?;
llamada: IDENT (argumentos)? SEPARADOR;
condic_aritmetico: IDENT comparadores (NUMERO | FLOAT | IDENT) INTERROGACION ((NUMERO COLON NUMERO) | (IDENT COLON IDENT)) SEPARADOR;

tipodedato: (VOID | INT | CHAR);
comparadores: (MAYOR | MENOR | MAYORIGUAL | MENORIGUAL | COMPARACION);
operadores: (MAS | MENOS | MULT | DIV);
argumentos: PARENTESISA (VOID | CADENA | IDENT)? ((COMA IDENT)| (COMA CADENA))* PARENTESISC;